package com.ethink.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.id.generator.IdGenerator;
import com.ethink.order.api.constant.OrderRespCode;
import com.ethink.order.api.enums.PurchaseOrderDetailStatusEnum;
import com.ethink.order.api.info.PurchaseOrderDetailInfo;
import com.ethink.order.api.info.PurchaseOrderInfo;
import com.ethink.order.api.info.SaleDemandOrderDetailInfo;
import com.ethink.order.api.model.PurchaseOrderDetailModel;
import com.ethink.order.api.model.PurchaseOrderNoAndQtyModel;
import com.ethink.order.api.model.PurchaseQuoteQueryModel;
import com.ethink.order.api.request.*;
import com.ethink.order.common.entity.PurchaseOrderDetail;
import com.ethink.order.common.entity.PurchaseQtyChangesLog;
import com.ethink.order.common.mapper.PurchaseOrderDetailMapper;
import com.ethink.order.common.mapper.PurchaseQtyChangesLogMapper;
import com.ethink.order.manager.SaleChannelRequestManager;
import com.ethink.order.service.PurchaseOrderDetailService;
import com.ethink.order.service.SaleDemandOrderDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 采购详情单 Service接口实现
 *
 * @author default
 * @date 2022-10-31
 */
@Slf4j
@Service
public class PurchaseOrderDetailServiceImpl extends ServiceImpl<PurchaseOrderDetailMapper, PurchaseOrderDetail> implements PurchaseOrderDetailService {

    @Autowired
    private PurchaseOrderDetailMapper purchaseOrderDetailMapper;

    @Autowired
    private SaleDemandOrderDetailService saleDemandOrderDetailService;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private PurchaseQtyChangesLogMapper purchaseQtyChangesLogMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<PurchaseOrderDetailInfo> queryPurchaseDetailOrderByDetailOrderNo(String detailOrderNo) {
        List<PurchaseOrderDetailInfo> detailInfos = purchaseOrderDetailMapper.queryPurchaseDetailOrderByDetailOrderNo(detailOrderNo);
        if (CollUtil.isEmpty(detailInfos)) {
            detailInfos = new ArrayList<>();
        }
        return detailInfos;
    }

    @Override
    public Integer updateLockOrderQty(LockOrderQtyUpdateRequest request) {
        PurchaseOrderDetail purchaseOrderDetail = purchaseOrderDetailMapper.selectById(request.getId());
        if (purchaseOrderDetail.getOrderNo() != null) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR.getCode(), "已生成采购订单,无法修改");
        }
        if (request.getLockOrderQty() >= purchaseOrderDetail.getLockOrderQty()){
            throw new BusinessException(CommonRespCode.SYSTEM_ERR.getCode(), "调整数量只能小于原数量");
        }
        //生成修改记录
        PurchaseQtyChangesLog log = new PurchaseQtyChangesLog();
        log.setPurchaseDetailId(purchaseOrderDetail.getId());
        log.setBeforeQty(purchaseOrderDetail.getLockOrderQty());
        log.setAfterQty(request.getLockOrderQty());
        log.setCreateUserCode(request.getCreateUserCode());
        log.setCreateUserName(request.getCreateUserName());
        purchaseQtyChangesLogMapper.insert(log);
        return purchaseOrderDetailMapper.update(null, new LambdaUpdateWrapper<PurchaseOrderDetail>()
                .eq(PurchaseOrderDetail::getId, request.getId())
                .set(PurchaseOrderDetail::getLockOrderQty, request.getLockOrderQty()));
    }

    @Override
    public PurchaseOrderDetailInfo queryDetailInfoByDetailId(Long id) {
        PurchaseOrderDetail purchaseOrderDetail = purchaseOrderDetailMapper.selectById(id);
        return BeanUtil.copyProperties(purchaseOrderDetail,PurchaseOrderDetailInfo.class);

    }

    @Override
    public List<PurchaseOrderNoAndQtyModel> queryPurchaseQty(List<String> orderNos) {
        return purchaseOrderDetailMapper.queryPurchaseQty(orderNos);
    }

    @Override
    public void purchaseQuote(PurchaseQuoteRequest request) {
        //查询销售信息
        SaleDemandOrderDetailInfo demandOrderDetailInfo = saleDemandOrderDetailService.queryByDetailOrderNo(request.getDetailOrderNo());
        //新增信息
        createOrUpdatePurchaseOrderDetail(request, demandOrderDetailInfo);
    }

    @Override
    public void bulkBindOrderNo(List<Long> ids, String orderNo) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        purchaseOrderDetailMapper.update(null, new LambdaUpdateWrapper<PurchaseOrderDetail>()
                .in(PurchaseOrderDetail::getId, ids)
                .set(PurchaseOrderDetail::getOrderNo, orderNo));
    }

    @Override
    public void saleLock(List<SaleLockRequest> item) {
        if (CollUtil.isEmpty(item)) {
            return;
        }
        for (SaleLockRequest saleLockRequest : item) {
            if (saleLockRequest.getLockOrderQty() > 0) {
                LambdaUpdateWrapper<PurchaseOrderDetail> wrapper = new LambdaUpdateWrapper();
                wrapper.eq(PurchaseOrderDetail::getId, saleLockRequest.getId())
                        .set(PurchaseOrderDetail::getLockOrderQty, saleLockRequest.getLockOrderQty())
                        .set(PurchaseOrderDetail::getIsLock, true);
                purchaseOrderDetailMapper.update(null, wrapper);
            }
        }
    }

    @Override
    public List<PurchaseOrderDetailModel> queryPrePurchaseOrder(PrePurchaseOrderQueryRequest request) {
        SaleChannelRequestManager.fill(request, 0, 1, 2);
        return purchaseOrderDetailMapper.queryPrePurchaseOrder(request);
    }

    @Override
    public Page<PurchaseOrderDetailModel> pageQuery(PurchaseOrderDetailPageQueryRequest request) {
        SaleChannelRequestManager.fill(request, 0, 1, 2);
        return purchaseOrderDetailMapper.pageQuery(PageUtils.buildPage(request), request);
    }

    @Override
    public Integer update(PurchaseOrderDetailUpdateRequest request) {
        //校验订单状态
        PurchaseOrderDetail purchaseOrderDetail = purchaseOrderDetailMapper.selectById(request.getId());
        if (!PurchaseOrderDetailStatusEnum.S1.getIntValue().equals(purchaseOrderDetail.getDetailOrderStatus())) {
            throw new BusinessException(OrderRespCode.PURCHASE_ORDER_DETAIL_STATUS_IS_NOT_MET);
        }
        PurchaseOrderDetail updateInfo = BeanUtil.copyProperties(request, PurchaseOrderDetail.class);
        return purchaseOrderDetailMapper.updateById(updateInfo);
    }

    @Override
    public void saleUnlock(String detailOrderNo) {
        purchaseOrderDetailMapper.update(null, new LambdaUpdateWrapper<PurchaseOrderDetail>()
                .eq(PurchaseOrderDetail::getSaleDemandDetailOrderNo, detailOrderNo)
                .set(PurchaseOrderDetail::getIsLock, false)
                .set(PurchaseOrderDetail::getLockOrderQty, 0));
    }

    @Override
    public Integer purchaseDetailDelete(Long id) {
        PurchaseOrderDetail purchaseOrderDetail = purchaseOrderDetailMapper.selectById(id);
        if (!PurchaseOrderDetailStatusEnum.S1.getIntValue().equals(purchaseOrderDetail.getDetailOrderStatus())) {
            throw new BusinessException(OrderRespCode.PURCHASE_ORDER_DETAIL_STATUS_IS_NOT_MET);
        }
        return purchaseOrderDetailMapper.delById(id);
    }

    @Override
    public List<PurchaseQuoteQueryModel> purchaseQuoteQuery(String detailOrderNo, String createUserCode) {
        return purchaseOrderDetailMapper.quoteQuery(detailOrderNo, createUserCode);
    }

    @Override
    public  List<PurchaseOrderDetailInfo>  winning(String saleDetailOrderNo) {
        List<PurchaseOrderDetailInfo> list = new ArrayList<>();
        List<PurchaseOrderDetail> detailList = purchaseOrderDetailMapper.selectList(new LambdaQueryWrapper<PurchaseOrderDetail>()
                .eq(PurchaseOrderDetail::getSaleDemandDetailOrderNo, saleDetailOrderNo));
        if (CollUtil.isEmpty(detailList)) {
            return list;
        }
        for (PurchaseOrderDetail purchaseOrderDetail : detailList) {
            if (purchaseOrderDetail.getIsLock()) {
                PurchaseOrderDetailInfo purchaseOrderDetailInfo = BeanUtil.copyProperties(purchaseOrderDetail, PurchaseOrderDetailInfo.class);
                list.add(purchaseOrderDetailInfo);
                purchaseOrderDetail.setDetailOrderStatus(PurchaseOrderDetailStatusEnum.S2.getIntValue());
            } else {
                purchaseOrderDetail.setDetailOrderStatus(PurchaseOrderDetailStatusEnum.S3.getIntValue());
            }
            purchaseOrderDetailMapper.updateById(purchaseOrderDetail);
        }
        return list;
    }


    private void createOrUpdatePurchaseOrderDetail(PurchaseQuoteRequest request, SaleDemandOrderDetailInfo demandOrderDetailInfo) {
        List<PurchaseOrderDetail> detailList = new ArrayList<>();
        for (PurchaseQuoteRequest.Item item : request.getItem()) {
            PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
            if (item.getId() != null) {
                purchaseOrderDetail.setId(item.getId());
            }
            purchaseOrderDetail.setDetailOrderNo(idGenerator.cgDetail());
            purchaseOrderDetail.setSaleDemandOrderNo(demandOrderDetailInfo.getOrderNo());
            purchaseOrderDetail.setSaleDemandDetailOrderNo(demandOrderDetailInfo.getDetailOrderNo());
            purchaseOrderDetail.setDetailOrderStatus(PurchaseOrderDetailStatusEnum.S1.getIntValue());
            purchaseOrderDetail.setMateCode(demandOrderDetailInfo.getMateCode());
            purchaseOrderDetail.setMateName(demandOrderDetailInfo.getMateName());
            purchaseOrderDetail.setMateSku(demandOrderDetailInfo.getMateSku());
            purchaseOrderDetail.setMateSkuName(demandOrderDetailInfo.getMateSkuName());
            purchaseOrderDetail.setGeneraCode(demandOrderDetailInfo.getGeneraCode());
            purchaseOrderDetail.setMinorDefectsCode(demandOrderDetailInfo.getMinorDefectsCode());
            purchaseOrderDetail.setSubclassCode(demandOrderDetailInfo.getSubclassCode());
            purchaseOrderDetail.setBrandCode(demandOrderDetailInfo.getBrandCode());
            purchaseOrderDetail.setBrandName(demandOrderDetailInfo.getBrandName());
            purchaseOrderDetail.setInternationCode(demandOrderDetailInfo.getInternationCode());
            purchaseOrderDetail.setUnitCode(demandOrderDetailInfo.getUnitCode());
            purchaseOrderDetail.setUnitName(demandOrderDetailInfo.getUnitName());
            purchaseOrderDetail.setSupplierCode(item.getSupplierCode());
            purchaseOrderDetail.setSupplierName(item.getSupplierName());
            purchaseOrderDetail.setPurchasePrice(item.getPurchasePrice());
            purchaseOrderDetail.setPurchasePriceBb(item.getPurchasePrice().multiply(item.getExchangeRate()));
            purchaseOrderDetail.setCurrencyCode(item.getCurrencyCode());
            purchaseOrderDetail.setCurrencyName(item.getCurrencyName());
            purchaseOrderDetail.setPriceValidityPeriod(item.getPriceValidityPeriod());
            purchaseOrderDetail.setValidityPeriod(item.getValidityPeriod());
            purchaseOrderDetail.setAvailableQty(item.getAvailableQty());
            purchaseOrderDetail.setCreateUserCode(request.getCreateUserCode());
            purchaseOrderDetail.setCreateUserName(request.getCreateUserName());
            purchaseOrderDetail.setRemark(item.getRemark());
            purchaseOrderDetail.setPayType(item.getPayType());
            purchaseOrderDetail.setCategoryName(demandOrderDetailInfo.getCategoryName());
            purchaseOrderDetail.setProductSpecification(demandOrderDetailInfo.getProductSpecification());
            purchaseOrderDetail.setFinalPurchasePrice(item.getPurchasePrice());
            purchaseOrderDetail.setDeliveryPlace(item.getDeliveryPlace());
            purchaseOrderDetail.setDeliveryWay(item.getDeliveryWay());
            purchaseOrderDetail.setExpectSupplierTime(item.getExpectSupplierTime());
            detailList.add(purchaseOrderDetail);
        }
        if (CollUtil.isNotEmpty(detailList)) {
            saveOrUpdateBatch(detailList);
        }
    }

}
